package com.pactera.madp.cp.service.sync.impl;

import cn.hutool.core.date.DateUtil;
import com.pactera.madp.cp.common.constant.Constants;
import com.pactera.madp.cp.common.enums.sync.FinaServiceEnum;
import com.pactera.madp.cp.common.util.RedisUtil;
import com.pactera.madp.cp.context.SyncStateContext;
import com.pactera.madp.cp.service.ProdService;
import com.pactera.madp.cp.service.sync.FinaSyncBusinessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class FinaSyncBusinessServiceImpl implements FinaSyncBusinessService {

    private final RedisTemplate redisTemplate;
    private final ProdService prodService;

    @Override
    public Boolean syncBusiness() {
        String nowDate = DateUtil.format(new Date(), Constants.DATE_FORMAT);
        String serialNum = (String) redisTemplate.boundValueOps(Constants.SYNC_FINA_SERIAL_NUM).get();

        // 校验触发同步的阀值
        String thresholdKey = RedisUtil.buildKey(Constants.SYNC_FINA_THRESHOLD, serialNum);
        long threshold = redisTemplate.boundValueOps(thresholdKey).increment();
        if (!SyncStateContext.get().isExeBusiness() || threshold != FinaServiceEnum.PRD.getSyncThreshold()) {
            log.info(SyncStateContext.get().getSyncSubType() + "-threshold-" + threshold + ",isExe-" + SyncStateContext.get().isExeBusiness());
            return false;
        } else {
            log.info("产品业务同步开始执行");
            // 重置触发值，避免二次执行时重复执行
            Set keys = redisTemplate.keys(Constants.SYNC_FINA_THRESHOLD + "*");
            keys.forEach(k -> redisTemplate.delete(k));
        }

        // 执行同步业务
        String lockKey = RedisUtil.buildKey(Constants.SYNC_FINA_BUSINESS_LOCK, nowDate);

        try {
            // 获取同步业务的锁
            boolean isLocked = RedisUtil.getLock(lockKey, "1", Constants.EXPIRE_TIME, TimeUnit.SECONDS);
            if (!isLocked) {
                SyncStateContext.get().setSaveLog(false);
                return false;
            }
            log.info("产品业务同步获取锁成功");

            // 同步产品数据
            Boolean flag = prodService.syn(1);
            if (flag) {
                log.info("产品业务同步执行成功");
            }
            return flag;
        } finally {
            redisTemplate.delete(lockKey);
            log.info("产品业务同步释放锁成功");
        }
    }

}
